package auctions;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Vector;

import javax.xml.parsers.*;

import org.w3c.dom.Document;


public class AuctionHouseImpl implements AuctionHouse {

	private int _numBidders;
	private int _numAuctions;
	private Vector<Integer> _paymentRule;
	private Vector<Agent> _agents;
	private Vector<Double> _reserves;
	
	private String _outputFile;
	
	private Document _doc;
	
	public AuctionHouseImpl(String outputFile, int numBidders, int numAuctions, Vector<Integer> paymentRule, Vector<Double> reserves) {
		_outputFile = outputFile;
		_numBidders = numBidders;
        _numAuctions = numAuctions;
        this.setPaymentRule(paymentRule);
        this.setReserve(reserves);
		
	}
	
	@Override
	public Vector<AuctionResults> getWinner() {
		/**
		 * Asks each agent for its bid in each auction and determines the
		 * winner by keeping track of the highest bid.
		 * 
		 * NOTE: A bid class could be added which would include bid and time
		 * so that we could break tied bids by who submitted the bid first
		 */
		Vector<AuctionResults> results = new Vector<AuctionResults>();
		for (int i = 0; i< _numAuctions; i++) {
			//For each auction accumulate bids
			double maxBid = 0;
			int maxBidder = 0;
			Vector<Double> bids = new Vector<Double>();  //This could be extended
			for (int agent = 0; agent<_agents.size(); agent++) {
				 bids.add(_agents.get(agent).getBid(i));
				 if (bids.get(agent) > maxBid) {
					 maxBid = bids.get(agent);
					 maxBidder = agent;
				 }
			}
			
			//Now determine the winning price
			ArrayList<Double> sortedBids = new ArrayList<Double>(bids);
			Collections.sort(sortedBids);
			
			int priceIndex = sortedBids.size() - this._paymentRule.get(i);
			double price;
			if (priceIndex < 0)  { 
				price = this._reserves.get(i);
			} else { 
				price = sortedBids.get(priceIndex);
			}
			
			_agents.get(maxBidder).addWinnings(i, price);
			results.add(new AuctionResults(price, bids, maxBidder));
		}
		AuctionsToXML writer = new AuctionsToXML(results);
		writer.generateXML(_outputFile);
		return results;
		

	}


	@Override
	public void setNumSimulataneousAuctions(int numSimultaneousAuctions) {
		// TODO Auto-generated method stub
		_numAuctions = numSimultaneousAuctions;
	}

	@Override
	public void setPaymentRule(Vector<Integer> paymentRule) {
		/**
		 * Takes a vector of payment rules  (one for each auction)
		 * If the Vector of rules is smaller than the number of auctions
		 * all remaining rules are set to the last rule in
		 * the vector.  To give all auctions the same rule  pass
		 * in a vector with one element equal to the desired payment rule
		 */
		_paymentRule = new Vector<Integer>();
		
		for (int i = 0; i<this._numAuctions; i++) {
			if (i < paymentRule.size()) {
				_paymentRule.add(paymentRule.get(i));
			} else {
				_paymentRule.add(paymentRule.lastElement());
			}
			
		}
	}
	
	public void setAgents(Vector<Agent> agents) {
		_agents = agents;
		_numBidders = agents.size();
	}

	@Override
	public void setReserve(Vector<Double> reservePrices) {
		/**
		 * Takes a vector of reserve prices (one for each auction)
		 * If the Vector of reserves is less than the number of auctions
		 * all remaining reserves are set to the last reserve price in
		 * the vector.  To give all auctions the same reserve price pass
		 * in a vector with one element equal to the desired reserve price
		 */
		_reserves = new Vector<Double>();
		
		for (int i = 0; i<this._numAuctions; i++) {
			if (i < reservePrices.size()) {
				_reserves.add(reservePrices.get(i));
			} else {
				_reserves.add(reservePrices.lastElement());
			}
			
		}
		
	}

	@Override
	public Vector<Double> getReserves() {
		return this._reserves;
	}

    public int getSize(){
        return _numAuctions;
    }

}
